/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.mes.manager.impl;

import com.xy.biz.mes.dao.ManufactureOrderDao;
import com.xy.biz.mes.dao.ManufactureOrderGoodsDao;
import com.xy.biz.mes.domain.bo.ManufactureOrderBO;
import com.xy.biz.mes.domain.bo.ManufactureTaskBO;
import com.xy.biz.mes.domain.converter.ManufactureOrderConverter;
import com.xy.biz.mes.domain.converter.ManufactureOrderGoodsConverter;
import com.xy.biz.mes.domain.bo.ManufactureOrderGoodsBO;
import com.xy.biz.mes.domain.query.ManufactureOrderGoodsQuery;
import com.xy.biz.mes.domain.query.ManufactureOrderQuery;
import com.xy.biz.mes.domain.query.ManufactureTaskQuery;
import com.xy.biz.mes.manager.ManufactureOrderManager;
import com.xy.biz.mes.manager.ManufactureTaskManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author zsp
 * @date 2022-1-6
 */
@Service
public class ManufactureOrderManagerImpl implements ManufactureOrderManager {

    @Autowired
    private ManufactureOrderDao manufactureOrderDao;
    @Autowired
    private ManufactureOrderGoodsDao manufactureOrderGoodsDao;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public int saveAllManufactureOrder(Collection<ManufactureOrderBO> collection) {
        int affectedRows = manufactureOrderDao.saveAllManufactureOrder(ManufactureOrderConverter.toPO(collection));
        if (affectedRows > 0) {
            List<ManufactureOrderGoodsBO> manufactureOrderGoodsBOList = collection.stream()
                    .flatMap(e -> e.getGoodsList().stream()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(manufactureOrderGoodsBOList)) {
                affectedRows += saveAllManufactureOrderGoods(manufactureOrderGoodsBOList);
            }
        }
        return affectedRows;
    }

    /**
     * 保存多个
     *
     * @param collection
     */
    @Override
    public int saveAllManufactureOrderGoods(Collection<ManufactureOrderGoodsBO> collection) {
        return manufactureOrderGoodsDao.saveAllManufactureOrderGoods(
                ManufactureOrderGoodsConverter.toPO(collection));
    }

    @Override
    public int updateManufactureOrder(ManufactureOrderBO manufactureOrderBO) {
        return manufactureOrderDao.updateManufactureOrder(ManufactureOrderConverter.toPO(Arrays.asList(manufactureOrderBO)));
    }

    @Override
    public int updateAllManufactureOrder(Collection<ManufactureOrderBO> collection) {
        return manufactureOrderDao.updateManufactureOrder(ManufactureOrderConverter.toPO(collection));
    }

    @Override
    public int updateAllManufactureOrderGoods(Collection<ManufactureOrderGoodsBO> collection) {
        return manufactureOrderGoodsDao.updateAllManufactureOrderGoods(ManufactureOrderGoodsConverter.toPO(collection));
    }

    @Override
    public int deleteManufactureOrder(Long manufactureOrderId) {
        return manufactureOrderDao.deleteManufactureOrder(manufactureOrderId);
    }

    @Override
    public int deleteManufactureOrderGoods(Collection<Long> manufactureOrderGoodsIdCollection) {
        return manufactureOrderGoodsDao.deleteManufactureOrderGoods(manufactureOrderGoodsIdCollection);
    }

    @Override
    public ManufactureOrderBO getManufactureOrder(Long manufactureOrderId) {
        return ManufactureOrderConverter.fromPO(manufactureOrderDao.getManufactureOrder(manufactureOrderId));
    }

    @Override
    public List<ManufactureOrderBO> listManufactureOrderById(Collection<Long> collection, boolean withGoods) {
        List<ManufactureOrderBO> manufactureOrderBOList
                = ManufactureOrderConverter.fromPO(manufactureOrderDao.listManufactureOrderById(collection));
        build(manufactureOrderBOList, withGoods);
        return manufactureOrderBOList;
    }

    @Override
    public List<ManufactureOrderGoodsBO> listManufactureOrderGoodsById(Collection<Long> collection) {
        if (CollectionUtils.isEmpty(collection)) {
            return Collections.emptyList();
        }
        return ManufactureOrderGoodsConverter.fromPO(manufactureOrderGoodsDao.listManufactureOrderGoods(ManufactureOrderGoodsQuery.max()
                .manufactureOrderGoodsIdList(new ArrayList<>(collection)).build()));
    }

    @Override
    public List<ManufactureOrderBO> listManufactureOrder(ManufactureOrderQuery query) {
        List<ManufactureOrderBO> manufactureOrderBOList
                = ManufactureOrderConverter.fromPO(manufactureOrderDao.listManufactureOrder(query));
        build(manufactureOrderBOList, query.getWithGoods());
        return manufactureOrderBOList;
    }

    private void build(List<ManufactureOrderBO> manufactureOrderBOList, boolean withGoods) {
        if (CollectionUtils.isEmpty(manufactureOrderBOList)) {
            return;
        }
        Set<Long> manufactureOrderIdSet
                = manufactureOrderBOList.stream().map(ManufactureOrderBO::getManufactureOrderId).collect(Collectors.toSet());
        Map<Long, List<ManufactureOrderGoodsBO>> manufactureOrderGoodsBOMap = new HashMap<>();
        if (withGoods) {
            List<ManufactureOrderGoodsBO> manufactureOrderGoodsBOList
                    = ManufactureOrderGoodsConverter.fromPO(manufactureOrderGoodsDao.listManufactureOrderGoods(ManufactureOrderGoodsQuery.max()
                    .manufactureOrderIdList(new ArrayList<>(manufactureOrderIdSet))
                    .build()));
            manufactureOrderGoodsBOMap.putAll(manufactureOrderGoodsBOList.stream().collect(
                    Collectors.groupingBy(ManufactureOrderGoodsBO::getManufactureOrderId)));
        }
        for (ManufactureOrderBO manufactureOrderBO : manufactureOrderBOList) {
            manufactureOrderBO.setGoodsList(manufactureOrderGoodsBOMap.get(manufactureOrderBO.getManufactureOrderId()));
        }
    }

    @Override
    public int countManufactureOrder(ManufactureOrderQuery query) {
        return manufactureOrderDao.countManufactureOrder(query);
    }

}
